/*
 * Hidden Equity LLC
 * Author: Maksym Fedyay, Kyiv, mcsimf@gmail.com
 * Date: 29.02.2012
 */

package com.hiddenequity.acts;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import com.hiddenequity.adgroup_service.AdGroupResponseParser;
import com.hiddenequity.adgroup_service.AdGroupService;
import com.hiddenequity.campaign_service.CampaignResponseParser;
import com.hiddenequity.report_definition_service.PredicateOperator;
import com.hiddenequity.report_definition_service.ReportDefinitionResponseParser;
import com.hiddenequity.report_definition_service.ReportDefinitionService;
import com.hiddenequity.report_definition_service.ReportDialog;
import com.hiddenequity.report_definition_service.ReportField;
import com.hiddenequity.report_definition_service.ReportType;
import com.hiddenequity.utils.AppPreferences;
import com.hiddenequity.utils.AuthService;
import com.hiddenequity.utils.Communication;
import com.hiddenequity.utils.DateProcessor;
import com.hiddenequity.utils.UrlBuncher;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;

public class Act_AdGroupList extends Act_Super{

	private static ArrayList<HashMap<String, String>> adGroupList = new ArrayList<HashMap<String, String>>();
	
	private String campaignId;
	private String campaignName;
	private String campaignBidingStrategy;
	private String campaignBudget;
	
	private Spinner spinnerDateRange;
	private Spinner spinnerStatus;
	
	
	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		super.onConfigurationChanged(newConfig);
	}


	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.act_adgroup_list);

        Intent intent = getIntent();
        campaignId = intent.getStringExtra("campaignId");
        campaignBidingStrategy = intent.getStringExtra("biddingStrategy");
        campaignName = intent.getStringExtra("campaignName");
        campaignBudget = intent.getStringExtra("campaignBudget");
        
        title.setText(getString(R.string.title_adgroup_list));
        sub_title.setText(campaignName);
        
        //Populate date range list
        spinnerDateRange = (Spinner) findViewById(R.id.spin_CampaignDateRange);
        dateRangeItem = AppPreferences.LoadPreferenceInt("dateRange", 0, getApplication());
        inflateSpinner(spinnerDateRange, R.array.arr_dateRanges, dateRangeItem);
        
        spinnerDateRange.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
                try {
                	if(pos != dateRangeItem){
                		AppPreferences.SavePreferenceInt("dateRange", pos, getApplication());
                		dateRangeItem = pos;
                		runOperationAsync(OPERATION_GET_LIST, getString(R.string.progress_loading), false);
                	}
				} catch (Exception e) {
					e.printStackTrace();
				}
            	
            }
            public void onNothingSelected(AdapterView<?> parent) {
            }
            
        });

        //Populate status list
        spinnerStatus = (Spinner) findViewById(R.id.spin_CampaignStatus);
        statusItem = AppPreferences.LoadPreferenceInt("status", 0, getApplication());
        inflateSpinner(spinnerStatus, R.array.arr_status, statusItem);
        
        spinnerStatus.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
                try {
                	if(pos != statusItem){
                		AppPreferences.SavePreferenceInt("status", pos, getApplication());
                		statusItem = pos;
                		runOperationAsync(OPERATION_GET_LIST, getString(R.string.progress_loading), false);
                	}
				} catch (Exception e) {
					e.printStackTrace();
				}
            	
            }
            public void onNothingSelected(AdapterView<?> parent) {
            }
            
        });  
        
       
		//Filter toggler
		filterToggler(AppPreferences.LoadPreferenceInt("filterToggle", 0, getApplication()));
		final Button btn_toggleFilter = (Button) findViewById(R.id.btn_toggleFilter);
		btn_toggleFilter.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				LinearLayout filter = (LinearLayout) findViewById(R.id.ll_filter);
				filterToggler(filter.getVisibility());
			}
		});
        
        //List view 
        final ListView lv = (ListView) findViewById(R.id.list_AdGroup);
        registerForContextMenu(lv);
        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
	        public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
	        	Map<String, String> itemMap = (Map<String, String>) lv.getItemAtPosition(position);
	        	if(!itemMap.get("status").equals("DELETED"))
	        		showRedirectDialog(itemMap.get("id"), itemMap.get("name"));	
	        }
        });
        
        lv.setAdapter(adGroupListAdapter);
        
        runOperationAsync(OPERATION_GET_LIST, getString(R.string.progress_loading), false);

    }//onCreate
    

    /*
     * Show dialog with for user redirection
     */
    private void showRedirectDialog(final String adGroupId, final String adGroupName){
    	
    	final CharSequence[] items = {
    			getString(R.string.adgroup_ads), 
    			getString(R.string.adgroup_keywords),
    			getString(R.string.adgroup_negative_keywords)
    		};

    	AlertDialog.Builder builder = new AlertDialog.Builder(this);
    	builder.setTitle(adGroupName);
    	builder.setItems(items, new DialogInterface.OnClickListener() {
    	    public void onClick(DialogInterface dialog, int item) {
    	        
    	    	if(items[item].equals(getString(R.string.adgroup_ads))){
    	            Intent intent = new Intent(getBaseContext(), Act_AdList.class);
    	            intent.putExtra("adGroupId", adGroupId);
    	            intent.putExtra("campaignName", campaignName);
    	            intent.putExtra("adGroupName", adGroupName);
    	            startActivityForResult(intent, REQUEST_NO_REFRESH_REQUIRED);
    	    	}

    	    	if(items[item].equals(getString(R.string.adgroup_keywords))){
    	            Intent intent = new Intent(getBaseContext(), Act_KeywordList.class);
    	            intent.putExtra("adGroupId", adGroupId);
    	            intent.putExtra("campaignName", campaignName);
    	            intent.putExtra("adGroupName", adGroupName);
    	            intent.putExtra("campaignBidingStrategy", campaignBidingStrategy);
    	            intent.putExtra("campaignBudget", campaignBudget);
    	            intent.putExtra("criterionUse", true);
    	            startActivityForResult(intent, REQUEST_NO_REFRESH_REQUIRED);
    	    	}   	
    	    	
    	    	if(items[item].equals(getString(R.string.adgroup_negative_keywords))){
    	            Intent intent = new Intent(getBaseContext(), Act_KeywordList.class);
    	            intent.putExtra("adGroupId", adGroupId);
    	            intent.putExtra("campaignName", campaignName);
    	            intent.putExtra("adGroupName", adGroupName);
    	            intent.putExtra("campaignBidingStrategy", campaignBidingStrategy);
    	            intent.putExtra("criterionUse", false);
    	            startActivityForResult(intent, REQUEST_NO_REFRESH_REQUIRED);
    	    	}   
    	    }
    	});
    	AlertDialog alert = builder.create();
        alert.show();

    }//showRedirectDialog
    
    
    
    /*
     * Handles requested activity result
     */
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    	super.onActivityResult(requestCode, resultCode, data);
    	
    	filterToggler(AppPreferences.LoadPreferenceInt("filterToggle", 0, getApplication()));
    	
    	if(resultCode == RESPONSE_FINISH_REQUIRED){
			finishActivityWithResult(RESPONSE_FINISH_REQUIRED);
		} else if(resultCode == RESPONSE_GOTO_MAIN_ACTIVITY){
			finishActivityWithResult(RESPONSE_GOTO_MAIN_ACTIVITY);
		} else if(isFilterChanged(statusItem, dateRangeItem)){
			statusItem = AppPreferences.LoadPreferenceInt("status", 0, getApplication());
			dateRangeItem = AppPreferences.LoadPreferenceInt("dateRange", 0, getApplication());
			runOperationAsync(OPERATION_GET_LIST, getString(R.string.progress_refreshing), false);
		} else if(requestCode == REQUEST_REFRESH_REQUIRED && resultCode == RESPONSE_REFRESH_REQUIRED){
			runOperationAsync(OPERATION_GET_LIST, getString(R.string.progress_refreshing), false); 			
		}
    	
		spinnerStatus.setSelection(statusItem);
		spinnerDateRange.setSelection(dateRangeItem);
    	
   	}//onActivityResult  

    
 
    /*
     * Inflate Context menu when long press occurred (non-Javadoc)
     * @see android.app.Activity#onCreateContextMenu(android.view.ContextMenu, android.view.View, android.view.ContextMenu.ContextMenuInfo)
     */
    
    private String selectedAdGroupId;
    private String selectedAdGroupName;
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
    	super.onCreateContextMenu(menu, v, menuInfo);

    	switch (v.getId()) {
        	
			case R.id.list_AdGroup: 
			    AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)menuInfo;
			    ListView list = (ListView) v;
			    Map<String, String> itemMap = (Map<String, String>) list.getItemAtPosition(info.position);

				selectedAdGroupId = itemMap.get("id");
				selectedAdGroupName = itemMap.get("name");
				
				String status = itemMap.get("status");
				
			    menu.add(0, 1, 0, R.string.adgroup_general);
			    menu.add(0, 2, 0, R.string.performance_report);
			    
			    if(!status.equals("ENABLED"))
			    	menu.add(0, 3, 0, R.string.status_active);
			    
			    if(!status.equals("PAUSED"))
			    	menu.add(0, 4, 0, R.string.status_pause);
			    
			    if(!status.equals("DELETED"))
			    	menu.add(0, 5, 0, R.string.status_delete);
				
				break;
    	}
      	menu.setHeaderTitle(getString(R.string.tit_context_adgroup));
    }//onCreateContextMenu
    
    

    /*
     * Context menu selection handler  (non-Javadoc)
     * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
     */
    @Override
    public boolean onContextItemSelected(MenuItem item) {
    	Intent intent;

    	switch (item.getItemId()) {
        
    		case 1: 
    			intent = new Intent(this.getApplicationContext(), Act_AdGroupOperation.class);
    			intent.putExtra("adGroupId", selectedAdGroupId);
        		intent.putExtra("campaignBidingStrategy", campaignBidingStrategy);
        		intent.putExtra("campaignName", campaignName);
        		intent.putExtra("campaignBudget", campaignBudget);
    			startActivityForResult(intent, REQUEST_REFRESH_REQUIRED);            	
                break;

    		case 2: 
        		String[] fields = new String[] {
        				ReportField.ADGROUP_NAME,
        				ReportField.CLICKS,
        				ReportField.COST,
        				ReportField.IMPRESSION,
        				ReportField.STATUS,
        				ReportField.AVERAGE_POSITION,
        				ReportField.CONVERSIONS,
        				ReportField.AD_NETWORK_TYPE2,
        				ReportField.DEVICE,
        				ReportField.CLICK_TYPE
        				
            		};
        		
            	String[] predicateValue = new String[]{
            				selectedAdGroupId
        			};
        			
        			String[] predicates = new String[]{
        					ReportDefinitionService.setPredicator(ReportField.ADGROUP_ID, 
        							PredicateOperator.EQUALS, predicateValue)
        			};

        			String reportDefinition = ReportDefinitionService.defineReport(
            				ReportType.ADGROUP_PERFORMANCE_REPORT, fields, dateRangeItem, predicates);
            		String report = Communication.requestAdHogRequest(UrlBuncher.URL_ADHOC_REPORT, reportDefinition);
            		ReportDefinitionResponseParser parser = new ReportDefinitionResponseParser(report);
        			ArrayList<Map<String, String>> columns = parser.getReportColumns();
            		ArrayList<Map<String, String>> rows = parser.getReportRows(columns);
        			ReportDialog.showReport(Act_AdGroupList.this, rows, columns, 4, R.string.msg_title_adgroup_report).show();
                break;
                
    		case 3: 
    			statusSetTo = STATUS_ACTIVE;
    			runOperationAsync(OPERATION_SET_STATUS, getString(R.string.progress_applying), false);
                break;
                
            case 4: 
    			statusSetTo = STATUS_PAUSED;
    			runOperationAsync(OPERATION_SET_STATUS, getString(R.string.progress_applying), false);
                break;
                
            case 5: 
    			statusSetTo = STATUS_DELETED;
    			
    			new AlertDialog.Builder(this)
						.setTitle(R.string.msg_title_conf_delete)		
						.setMessage(getString(R.string.msg_conf_adgroup_delete) + " " + quote + selectedAdGroupName + quote + "?")
		    			.setPositiveButton(R.string.btn_Yes, deletionConfirmationListener)
			    		.setNegativeButton(R.string.btn_No, deletionConfirmationListener)
			    		.setCancelable(false)
			    		.create()
			    		.show();
    			               
    			break;
        }
        return true;
    }//onContextItemSelected

    
    
	/*
	 * Dialog onClick Listener
	 */
	private DialogInterface.OnClickListener deletionConfirmationListener = new DialogInterface.OnClickListener() {
		public void onClick(DialogInterface dialog, int which) {

			switch (which){
	        
		        case DialogInterface.BUTTON_POSITIVE:
		        	runOperationAsync(OPERATION_SET_STATUS, getString(R.string.progress_applying), false);
		            break;
	
		        case DialogInterface.BUTTON_NEGATIVE:
		        	//Do nothing on cancel
		            break;
	        }
	        
		}
	};//DialogClickListener
    

	
	/*
	 * Change adgroup status
	 */
	private void setAdGroupStatus(){
		
		String response = Communication.postSOAP(
				AdGroupService.URL_ADGROUP_SERVICE,
				AdGroupService.setAdGroupStatus(campaignId, selectedAdGroupId, statusSetTo));

		CampaignResponseParser campaignParser = new CampaignResponseParser(response);
		
		responseErrorString = campaignParser.checkForErrors();		
	}//setAdGroupStatus
    
    
    
	/*
     * Inflate Option menu called when menu button pressed (non-Javadoc)
     * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.option_adgroup_list, menu);
        return true;
    }//onCreateOptionsMenu
    

    
    /*
     *Option menu selection handler  (non-Javadoc)
     * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
    	
    	Intent intent;

    	switch (item.getItemId()) {
        	
    		case R.id.refresh_AdGroup:
   				runOperationAsync(OPERATION_GET_LIST, getString(R.string.progress_refreshing), false);
    			break;
    		
    		case R.id.add_AdGroup: 
        		intent = new Intent(this.getApplicationContext(), Act_AdGroupOperation.class);
            	intent.putExtra("campaignId", campaignId);
            	intent.putExtra("campaignBidingStrategy", campaignBidingStrategy);
        		intent.putExtra("campaignName", campaignName);
        		intent.putExtra("campaignBudget", campaignBudget);
            	startActivityForResult(intent, REQUEST_REFRESH_REQUIRED);            	
                break;
            
            case R.id.switch_AccountAdGroup: 
            	AuthService.performLogout(getApplication());
            	intent = new Intent(this.getApplicationContext(), Act_Login.class);
            	startActivityForResult(intent, REQUEST_REFRESH_REQUIRED);  
                break;
        }
        return true;
    }//onOptionsItemSelected
  
    
    /*
     * 
     */
	private BaseAdapter adGroupListAdapter = new BaseAdapter() {

		public int getCount() {
			int size = Act_AdGroupList.adGroupList.size();
			return size;
		}

		public Object getItem(int position) {
			return Act_AdGroupList.adGroupList.get(position);
		}

		public long getItemId(int position) {
			return position;
		}

		public View getView(int position, View convertView, ViewGroup parent) {
			View row = convertView;

			if (row == null) {
				LayoutInflater mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
				row = mInflater.inflate(R.layout.list_row_adgroup, null);
			}

			TextView adGroupName = (TextView) row.findViewById(R.id.adGroupName);
			TextView adGroupId = (TextView) row.findViewById(R.id.adGroupId);
			TextView adGroupStatus = (TextView) row.findViewById(R.id.adGroupStatus);
			TextView adgroup_avgcpc_value = (TextView) row.findViewById(R.id.adgroup_avgcpc_value);
			TextView adgroup_clicks_value = (TextView) row.findViewById(R.id.adgroup_clicks_value);
			TextView adgroup_cost_value = (TextView) row.findViewById(R.id.adgroup_cost_value);
			TextView adgroup_ctr_value = (TextView) row.findViewById(R.id.adgroup_ctr_value);
			ImageView img_adgroup_status = (ImageView) row.findViewById(R.id.img_adgroup_status);
			ImageView img_more =  (ImageView) row.findViewById(R.id.img_more);
			
			adGroupName.setText(Act_AdGroupList.adGroupList.get(position).get("name"));
			adGroupId.setText(Act_AdGroupList.adGroupList.get(position).get("id"));

			adgroup_avgcpc_value.setText(Act_AdGroupList.adGroupList.get(position).get("avgcpc"));
			adgroup_clicks_value.setText(Act_AdGroupList.adGroupList.get(position).get("clicks"));
			adgroup_cost_value.setText(Act_AdGroupList.adGroupList.get(position).get("cost"));
			adgroup_ctr_value.setText(Act_AdGroupList.adGroupList.get(position).get("ctr"));

			String status = Act_AdGroupList.adGroupList.get(position).get("status");
			adGroupStatus.setText(status);
			
			if(status.equals("ENABLED")){
				img_adgroup_status.setImageResource(R.drawable.enable);
				img_more.setVisibility(View.VISIBLE);
			} else if(status.equals("PAUSED")){
				img_adgroup_status.setImageResource(R.drawable.pause);
				img_more.setVisibility(View.VISIBLE);
			} else if(status.equals("DELETED")){
				img_adgroup_status.setImageResource(R.drawable.delete);
				img_more.setVisibility(View.INVISIBLE);
			}
			return row;
		}
	};
    

	
    /*
     * Async operation
     */
	private void runOperationAsync(final int operation, String message, boolean overlap) {
	
		//Stop if thread is alive
		if(thread.isAlive() && !overlap)
			return;
		
		//Show progress dialog
		final ProgressDialog progressDialog = ProgressDialog.show(this, "",
				message, true);

		//Check if Internet connection alive
		if(!isConnectionAvalable()){
			progressDialog.dismiss();
			return;
		}

		thread = new Thread(){
			public void run() {
				//Perform authentication
				new AuthService(Act_AdGroupList.this, getApplication());
				
				//Perform operation
				if (AuthService.authToken != null) {
					try {
						switch (operation) {
							case OPERATION_GET_LIST:
								Act_AdGroupList.this.getAdGroupList();
								Act_AdGroupList.this.getTip();
								break;
							case OPERATION_SET_STATUS:
								Act_AdGroupList.this.setAdGroupStatus();
								break;
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				
				//Perform postoperation
				Act_AdGroupList.this.runOnUiThread(new Runnable() {
					public void run() {
						
						progressDialog.dismiss();

						if (AuthService.authToken != null) {
							
							showOperationError(R.string.msg_title_error, responseErrorString);
							
							switch (operation) {
								case OPERATION_GET_LIST:
									adGroupListAdapter.notifyDataSetChanged();
									showStatsTotal(SHOW_TOTALS_CLICKS_COST_CTR_AVGCPC);
									showTip();
									break;
								
								case OPERATION_SET_STATUS:
									runOperationAsync(OPERATION_GET_LIST, getString(R.string.progress_refreshing), true);
									break;
							}							
			
						} else {
							Intent intent = new Intent(Act_AdGroupList.this.getApplicationContext(),
									Act_Login.class);
							startActivityForResult(intent, REQUEST_REFRESH_REQUIRED);
						}
					}
				});
			}
		};
		thread.start();
	}//runOperationAsync

	
	  
    /*
     * Get AdGroup List
     */
    private void getAdGroupList(){   	
        adGroupList.clear();
    	
        AdGroupResponseParser parser = new AdGroupResponseParser(
        		Communication.postSOAP(
        				AdGroupService.URL_ADGROUP_SERVICE, 
        				AdGroupService.getAdGroupList(campaignId, DateProcessor.getDateRange(dateRangeItem)
        						, statusItem)
        				)
        			);
    	
        responseErrorString = parser.checkForErrors();
        
        adGroupList.addAll(parser.getAdGroupList());
    }//getListOfCampaigns
    
}
